SLaTeX's control sequences

You've already seen the SLaTeX control sequence \scheme and the environment schemedisplay. These suffice for quite a few instances of handling code in LATEX. However, you will occasionally require more control on the typesetting process, and the following complete1 list of SLaTeX control sequences shows you the ropes.

\begin{schemedisplay}
\end{schemedisplay}

Typesets its argument, which is usually several lines of indented code, and which is enclosed in arbitrary but identical characters, as displayed code. E.g.,

\begin{schemedisplay}
(define compose          ;this is also known as $B$
  (lambda (f g)
    (lambda (x)
      (apply f (g x)))))
\end{schemedisplay}

produces


\begin{schemedisplay}
(define compose ;this is also known as $B$
(lambda (f g)
(lambda (x)
(apply f (g x)))))
\end{schemedisplay}
enableslatex

Comments in Scheme are usually introduced by `;'. The rest of the line after a `;' is set as a line in LaTeX LR mode.

Separate blocks of code can either be introduced in different schemedisplay environments or put in a single schemedisplay and separated by a line with a `;' in the first column. This `;' is not typeset and anything following it on the line is set in LaTeX LR paragraph mode. I.e., consecutive lines with `;' in the first column are treated as input for a LaTeX paragraph, with words possibly moved around from line to line to ensure justification. E.g.,

\begin{schemedisplay}
(define even?               ; testing {\it even\/}ness
  (lambda (n)
    (if (= n 0) #t (not (odd? (- n 1))))))
;
; The procedures {\it even?\/} above
; and {\it odd?\/} below are mutually
; recursive.
;
(define odd?              ; testing {\it odd\/}ness
  (lambda (n)
    (if (= n 0) #f (not (even? (- n 1))))))
\end{schemedisplay}

produces


\begin{schemedisplay}
(define even? ; testing {\it even\/}ness
(lambda (n)
(if...
.../}ness
(lambda (n)
(if (= n 0)  ...
enableslatex

Note: see schemeregion.

\scheme

Typesets its argument, which is enclosed in arbitrary but identical non-alphabetic and non-{ characters, as in-text code. Special case: \scheme{...} is a convenience (provided the ... doesn't contain a }) E.g., \scheme|(call/cc (lambda (x) x))| and \scheme{(call/cc (lambda (x) x))} both produce (call/cc (lambda (x) x)). enableslatex

It is permitted to intermix calls to schemedisplay and \scheme. Thus,

\begin{schemedisplay}
(define factorial
  (lambda (n)
    (if (= n 0) ; \scheme{(zero? n)} also possible
        1
        (* n (factorial (- n 1)))))) ; or \scheme{... (sub1 1)}
\end{schemedisplay}

produces


\begin{schemedisplay}
(define factorial
(lambda (n)
(if (= n 0) ; \scheme{(zer...
...
1
(* n (factorial (- n 1)))))) ; or \scheme{... (sub1 1)}
\end{schemedisplay}
enableslatex

Note: see schemeregion.

\schemeresult

Typesets its argument, which is enclosed in arbitrary but identical non-alphabetic and non-{ characters, as in-text Scheme ``result'' or data: i.e., keyword and variable fonts are disabled. Special convenient case (as for \scheme): \schemeresult{...}. E.g.,

\scheme|((lambda () (cons 'lambda 'cons)))| yields
\schemeresult|(lambda . cons)|.

produces

|((lambda () (cons 'lambda 'cons)))| yields |(lambda . cons)|. enableslatex

\begin{schemebox}
\end{schemebox}

The schemebox environment is similar to schemedisplay except that the code is provided as a box (i.e., it is not displayed in the standard way). Saving it in an explicit box allows you to move your typeset code arbitrarily.

Note: see schemeregion.

\schemeinput

This can be used to input Scheme files as typeset code. (Unlike LaTeX's \input, \schemeinput's argument must always be grouped.) The Scheme file is specified by its full name, or without its extension, if this is .ss. E.g.,

\schemeinput{evenodd.ss}    % the .ss is optional!    

(where evenodd.ss is the name of a Scheme file containing the code for even? and odd? above) produces the same effect as the enableslatex schemedisplay version.

Note: see schemeregion.

\begin{schemeregion}
\end{schemeregion}

Calls to scheme, \schemeresult, schemedisplay, schemebox or schemeinput can be nested in (a Scheme comment) of other calls. In LaTeX text, they can occur in bodies of environments or otherwise grouped. However, they cannot normally be passed as arguments to macros or included in bodies of macro definitions, even though these are complete calls and not parameterized with respect to macro arguments. To be able to do this, you should cordon off such a text with the schemeregion environment. SLaTeX is fairly generous about where exactly you throw the cordon.

E.g., you cannot have

...
The boxed code \fbox{\scheme{(call/cc I)}} is ...
...

but you can have

\begin{schemeregion}
...
The boxed code \fbox{\scheme(call/cc I)}} is ...
... 
\end{schemeregion}

and this will produce


\begin{schemeregion}
\ldots
\par
The boxed code \fbox{\scheme{(call/cc I)}} is \ldots
\par
\ldots
\end{schemeregion}
enableslatex

Thus, the schemeregion environment makes it possible to put SLaTeX-specific commands inside macro arguments or macro definitions without causing rupture. Normally, this can't be done since SLaTeX-specific commands correspond to comment-like regions of LaTeX code once SLaTeX is done preprocessing your text. These comment regions share the characteristic of LaTeX's verbatim regions, which also can't appear in macro arguments or definitions.

To solve this, you enclose the offending text in a schemeregion environment. This ``inlines'' all the calls to SLaTeX in its body instead of commenting them and then invoking \input, thus escaping the fate described above. They are no-ops as far as non-SLaTeX commands are concerned. However, while a schemeregion allows its constituent SLaTeX commands to be included in macro arguments and bodies, it itself cannot be so included. Thus, your schemeregion should be in a position that satisfies the property A: either directly at the ``top-level'' or in a LaTeX environment that satisfies A. Since this recursive rule might look weird, you may just stick to calling schemeregion at the ``top-level''. Or, you may even wrap each of your LaTeX files in one huge schemeregion if you so wish. This will cover any obscure ``non-robust'' use of the SLaTeX primitives – however, SLaTeX will run slower. (The term ``robust'' is not necessarily used in the same sense as in LaTeX.)

Note that SLaTeX commands are made robust only if they are surrounded textually (lexically) by a schemeregion. A region marker doesn't have dynamic scope in the sense that LaTeX files loaded using \input from within a schemeregion will not inherit it. In summary, a schemeregion makes ``robust'' all calls to \scheme, schemedisplay, schemebox and \schemeinput within it.

\setkeyword
\setconstant
\setvariable

SLaTeX has a database containing information about which code tokens are to be treated as keywords, which as constants, and which as variables. However, there will always be instances where the user wants to add his or her own tokens to these categories, or perhaps even modify the categories as prescribed by SLaTeX. The control sequences that enable the user to do these are \setkeyword, \setconstant, and \setvariable. Their arguments are entered as a (space-separated) list enclosed in braces ({}): SLaTeX learns that these are henceforth to be typeset in the appropriate font. E.g.,

\setconstant{infinity -infinity}

tells SLaTeX that infinity and -infinity are to be typeset as constants. (The user need not specify such new keywords as are introduced by Scheme's extend-syntax: SLaTeX automatically recognizes them.) enableslatex

\setspecialsymbol
\unsetspecialsymbol

These commands are useful to generate ``mathematical''-looking typeset versions of your code, over and beyond the fonting capabilities provided by default. For instance, although your code is restricted to using ascii identifiers that follow some convention, the corresponding typeset code could be more mnemonic and utilize the full suite of mathematical and other symbols provided by TeX. This of course should not require you to interfere with your code itself, which should run in its ascii representation. It is only the typeset version that has the new look. For instance, you might want all occurrences of lambda, and, equiv?, below?, above?, a1 and a2 in your code to be typeset as λ, ∧, ≡, $\sqsubseteq$, $\sqsupseteq$, a1 and a2 respectively. To do this, you should \setspecialsymbol the concerned identifier to the desired TeX expansion, viz.

\setspecialsymbol{lambda}{$\lambda$}
\setspecialsymbol{and}{$\land$}
\setspecialsymbol{equiv?}{$\equiv$}
\setspecialsymbol{below?}{$\sqsubseteq$}
\setspecialsymbol{above?}{$\sqsupseteq$}
\setspecialsymbol{a1}{$a_1$}
\setspecialsymbol{a2}{$a_2$}
enableslatex

Now, typing

\begin{schemedisplay}
(define equiv?
  (lambda (a1 a2)
    (and (below? a1 a2) (above? a1 a2))))
\end{schemedisplay}

produces


\begin{schemedisplay}
(define equiv?
(lambda (a1 a2)
(and (below? a1 a2) (above? a1 a2))))
\end{schemedisplay}

enableslatex

Note that with the above settings, lambda and and have lost their default keyword status, i.e. they will not be typed boldface. To retrieve the original status of special symbols, you should use \unsetspecialsymbol, e.g.

\unsetspecialsymbol{lambda and}

Typing the same program after unsetting the special symbols as above produces, as expected:


\begin{schemedisplay}
(define equiv?
(lambda (a1 a2)
(and (below? a1 a2) (above? a1 a2))))
\end{schemedisplay}
enableslatex

In effect, this logically extends the basic ``fonting'' capability to arbitrary special typset versions.

\schemecasesensitive

SLaTeX always typesets output that is of the same case as your input, regardless of the setting of the \schemecasesensitive command. However, this command can be used to signal to SLaTeX that all case variations of an identifier are to be treated identically. E.g. typing \schemecasesensitive{false} implies that while lambda continues to be a keyword, so also are Lambda, LAMBDA and LaMbDa. \schemecasesensitive{true} reverts it back to the default mode where case is significant in determining the class of a token.

Note that the status \schemecasesensitive also affects the ``special symbols'' of the previous item. Thus, in the default case-sensitive setting, only the case-significant symbol as mentioned in the call to \setspecialsymbol will be replaced by the corresponding LaTeX expansion. In a case-insensitive setting, all case variations of the special symbol will be replaced.

\abovecodeskip
\belowcodeskip
\leftcodeskip
\rightcodeskip

These are the parameters used by schemedisplay for positioning the displayed code. The default values are

\abovecodeskip=\medskipamount
\belowcodeskip=\medskipamount
\leftcodeskip=0pt
\rightcodeskip=0pt

This produces a flushleft display. The defaults can be changed to get new display styles. E.g., the assignment

\leftcodeskip=5em

shifts the display from the left by a constant 5 ems.

On the other hand, the assignments

\leftcodeskip=0pt plus 1fil
\rightcodeskip=0pt plus 1fil

produce a centered display style.

\keywordfont
\constantfont
\variablefont

These decide the typefaces used for keywords, constants, and variables. The default definitions are:

\def\keywordfont#1{{\bf#1}}
\def\constantfont#1{{\sf#1}}
\def\variablefont#1{{\it#1\/}}

This is close to the Little Lisper [3] style. Redefine these control sequences for font changes. As an extreme case, defining all of them to {{\tt#1}} typesets everything in monospace typewriter font, as in [1].

\defschemedisplaytoken
\defschemetoken
\defschemeresulttoken
\defschemeboxtoken
\defschemeinputtoken
\defschemeregion

These define the tokens used by SLaTeX to trigger typesetting of in-text code, display code, box code, and Scheme files. The default tokens are, as already described, schemedisplay, \scheme, \schemeresult, schemebox, \schemeinput and schemeregion respectively. If you want shorter or more mnemonic tokens, the \defscheme*token control sequences prove useful. E.g., if you want \code to be your new control sequence for in-text code, use \defschemetoken{code}. All instances of \code+...+ after this definition produce in-text code, unless overridden by an \undefschemetoken command.

One can have at any time any number of tokens for the same activity. One consequence of this is that one can have nested schemeregions, provided one has different names for the nested call. Otherwise, the \end of an inner region will prematurely terminate an outer region.

\undefschemedisplaytoken
\undefschemetoken
\undefschemeresulttoken
\undefschemeboxtoken
\undefschemeinputtoken
\undefschemeregion

These undefine the tokens used for triggering typesetting in-text code, display code, box code, Scheme files, and robust Scheme regions. Use these if you want to use these tokens for other purposes and do not want to unwittingly trip up the SLaTeX system.

\defschememathescape
\undefschememathescape

\defschememathescape{$} defines the character $ as a mathematical escape character to be used within scheme code. (Any character other than } and whitespace may be chosen instead of $.) This allows one to use LaTeX-like mathematical subformulas within Scheme code, e.g.,

\defschememathescape{$}

\begin{schemedisplay}
(define $\equiv$
  (lambda (a$_1$ a$_2$)
    ($\land$ ($\sqsubseteq$ a$_1$ a$_2$) 
	     ($\sqsupseteq$ a$_1$ a$_2$))))     
\end{schemedisplay}

produces


\begin{schemedisplay}
(define $\equiv$
(lambda (a$_1$\ a$_2$)
($\land$\ ($\sqsubseteq$\ a$_1$\ a$_2$)
($\sqsupseteq$\ a$_1$\ a$_2$))))
\end{schemedisplay}

enableslatex

\undefschememathescape{$} disables the math-escape nature, if any, of $.

\slatexdisable

The tokens for typesetting code, as also the token \input (which is sensitive to SLaTeX, since the latter uses it to recursively process files within files), can only be used as calls. If they occur in the bodies of macro definitions, or their names are used for defining other control sequences, SLaTeX will not be able to process them. Sometimes, one wants to use these tokens, say \input, without having SLaTeX try to process the inputted file. Or the name \scheme may be used in a verbatim environment, and we don't want such an occurrence to trigger the codesetting half of SLaTeX to look for code.

Avoiding such uses altogether can be unduly restrictive (especially when you're writing a ``How to ...'' paper like this where you both use and mention the control sequences!). One way out is to judiciously use the \undefscheme*token commands to temporarily remove the SLaTeX-specificity of these names. Even this can be painful. SLaTeX therefore provides the commands \slatexdisable. This takes one argument word and makes the corresponding control sequence out of it. Further, from this point in the text, SLaTeX is disabled until the manufactured control sequence shows up. This mechanism makes it possible to restrict SLaTeX to only appropriate portions of the text. Note that the token \slatexdisable itself can appear in the text succeeding its call. The only token that can restore SLaTeX-sensitivity is the one created during the call to \slatexdisable.

A typical example of the use of \slatexdisable is when you use the names \scheme and \begin{schemedisplay} in a verbatim environment. E.g.,


\slatexdisable{slatexenable} 

\begin{verbatim}
slatex provides the command \scheme and the pair
\begin{schemedisplay} and \end{schemedisplay} to typeset
in-text and displayed Scheme code respectively.
\end{verbatim}
\slatexenable

produces the required

slatex provides the command \scheme and the pair
\begin{schemedisplay} and \end{schemedisplay} to typeset
in-text and display Scheme code respectively.

\slatexignorecurrentfile

This is a SLaTeX pragma included to improve efficiency. If you're sure that the remaining portion of a certain LaTeX (or TeX) file (including the files that would be \inputed by it) don't contain any SLaTeX commands, then you may place this control sequence in it at this point to signal SLaTeX that no preprocessing is necessary for the rest of the file.